import { path, successCode, tokenVarName, tokenPosition } from "@/config"
import replay from "./replay"
import { store } from "@/store"

class require {
	/**
	 * 处理传入的 options, 格式化并赋予其初始值
	 * @param {object} options
	 * @returns {object}
	 */
	optionsHandle(options = {}) {
		if (!options.url) {
			console.error("请求时 url 值错误: " + options.url)
			return false
		}
		if (!/^http/.test(options.url)) {
			options.url = path + options.url
		}
		options.method = (options.method && options.method.toUpperCase()) || "GET"
		options.header = options.header || {}

		if (options.token == undefined || options.token == null || options.token == true) {
			options.token = uni.getStorageSync("token") || ""
		}

		return {
			...options,
		}
	}
	/**
	 * @param {string} url
	 * @param {object} options
	 * @returns {Promise}
	 */
	request(url = "", options = {}) {
		if (typeof url === "string") {
			options.url = url
		} else {
			options = url
		}

		options = this.optionsHandle(options)
		if (!options) return Promise.reject()

		if (options.loading) {
			uni.showLoading({
				title: typeof options.loading === "string" ? options.loading : "加载中...",
				mask: true,
			})
		}
		const data = {
			...options.data,
		}
		const header = {
			// "Content-Type": "application/x-www-form-urlencoded",
			...options.header,
		}
		if (options.token) {
			if (tokenPosition == "data") {
				if (!options.data[tokenVarName]) {
					data[tokenVarName] = options.token
				}
			} else if (tokenPosition == "header") {
				if (!options.header[tokenVarName]) {
					header[tokenVarName] = options.token
				}
			}
		}

		if (options.log) {
			console.log(options.method + " | " + options.url)
			console.log("data: " + JSON.stringify(data))
			console.log("header: " + JSON.stringify(header))
		}

		return new Promise((reslove, reject) => {
			uni.request({
				url: options.url,
				method: options.method || "GET",
				data,
				header,
				success(e) {
					if (options.loading) uni.hideLoading()

					if (e.statusCode === 200) {
						if (e.data.code == successCode) {
							options.success && options.success.call(this, e.data.data)
							reslove(e.data.data)
						} else if (e.data.code === -1) {
							replay(options)
								.then(result => {
									options.success && options.success.call(this, result)
									reslove(result)
								})
								.catch(error => {
									options.fail && options.fail.call(this, error)
									reject(error)
								})
						} else if (e.data.code == 401 || e.data.code == 1000) {
							uni.showToast({
								title: "登录失效,请重新登录",
								icon: "none",
							})

							store.commit("logout")
						} else {
							options.fail && options.fail.call(this, e.data.msg)
							reject(e.data.msg)
						}
					} else {
						console.log("error: ", e)
						options.fail && options.fail.call(this, "接口错误")
						reject(e.data.msg || "接口错误")
					}
				},
				fail(e) {
					console.log("url: ", options.url)
					console.log("error: ", e)
					if (options.loading) uni.hideLoading()
					options.fail && options.fail.call(this, e || "接口错误")
					reject("接口错误")
				},
			})
		})
	}
}

export default new require()
